/*
 by txdnet.cn Tonydon
 */
package txdnet.util.image;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import txdnet.util.DataUtil;
import txdnet.util.Logger;

/**
 * @author txdnet
 */
public final class ImageVerifier {

    private static Class clazz = ImageVerifier.class;

    private ImageVerifier() {
    }
    private static Color[] COLR = {
        Color.LIGHT_GRAY, Color.ORANGE,
        Color.MAGENTA, Color.RED,
        Color.WHITE, Color.GREEN, Color.YELLOW
    };
    private static BasicStroke[] STROKE = {
        new BasicStroke(2),
        new BasicStroke(3)
    };

    // 得到随机字符串，输出图像流到客户端
    public static String getImageStr(
            int num,
            int w,
            int h,
            int pixSize,
            int pixNum,
            boolean bMixcolr,
            boolean bRot,
            int[] fontcolr,
            int[] bgcolr,
            boolean bDwLine,
            boolean bDwArc,
            char[] chrMap,
            Font font,
            String imgMime,
            OutputStream os) {
        String s;
        StringBuilder sb = new StringBuilder(num);
        for (int k = 0; k < num; k++) {
            sb.append(chrMap[genInt(0, chrMap.length)]);
        }
        s = sb.toString();
        outputImage(w, h, pixSize, pixNum, bMixcolr, bRot, fontcolr, bgcolr, bDwLine, bDwArc, s, font, imgMime, os);
        return s;
    }

    // 输入随机字符串，输出图像流到客户端
    public static void outputImage(
            int w,
            int h,
            int pixSize,
            int pixNum,
            boolean bMixcolr,
            boolean bRot,
            int[] fontcolr,
            int[] bgcolr,
            boolean bDwLine,
            boolean bDwArc,
            String vStr,
            Font font,
            String imgMime,
            OutputStream ostr) {
        BufferedImage bimg;
        Graphics2D g2d;

        int num = vStr.length();

        bimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        g2d = bimg.createGraphics();
        // 优化字体
        g2d.setRenderingHint(
                RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);

        Color c1 = new Color(bgcolr[genInt(0, bgcolr.length)]);
        g2d.setColor(c1);
        g2d.setBackground(c1);
        g2d.fillRect(0, 0, w, h);

        g2d.setFont(font);

        int hh = (h >> 1) + num;
        int ct_f = (pixSize >> 1);
        int mn = (num << 1);
        int ph = (ct_f + num);
        if (bRot) { // 是否倾斜字体
            int cr_x = 0; //记录移动的X坐标
            int cr_v; //增加的x位移
            double rot;
            int ct_y = h >> 1;
            int cc_f = (ct_f >> 1) - 2;
            // 先将坐标移到left-center.
            g2d.translate(num, ct_y);
            for (int k = 0; k < num; k++) {
                g2d.setColor(new Color(fontcolr[genInt(0, fontcolr.length)]));
                rot = Math.toRadians(genInt(-45, 31)); // 倾斜角度范围
                g2d.rotate(rot);
                g2d.drawString(vStr.substring(k, k + 1), cc_f, ct_f - 3);
                // g2d.drawLine(0, 0, pixSize, 0);
                // 复原角度
                g2d.rotate(-rot);
                // 再横向平移
                cr_v = genInt(ct_f, ct_f + num);
                g2d.translate(cr_v, 0);
                cr_x += cr_v;
            }
            //恢复原点
            g2d.translate(-cr_x, -ct_y);
        } else {
            for (int k = 0; k < num; k++) {
                g2d.setColor(new Color(fontcolr[genInt(0, fontcolr.length)]));
                g2d.drawString(vStr.substring(k, k + 1), (k * ph) + mn, genInt(pixSize, h - 2));
            }
        }

        if (pixNum > 0) { //画点
            int x, y, z;
            if (bMixcolr) {
                for (int k = 1; k <= pixNum; k++) {
                    g2d.setColor(COLR[genInt(0, COLR.length)]);
                    x = genInt(2, w - 2);
                    y = genInt(2, h - 2);
                    z = genInt(-1, 2);
                    g2d.drawLine(x, y, x + z, y - z);
                }
            } else {
                g2d.setColor(COLR[genInt(0, COLR.length)]);
                for (int k = 1; k <= pixNum; k++) {
                    x = genInt(2, w - 2);
                    y = genInt(2, h - 2);
                    z = genInt(-1, 2);
                    g2d.drawLine(x, y, x + z, y - z);
                }
            }
        }

        if (bDwArc) { // 画三条干扰曲线
            g2d.setColor(COLR[genInt(0, COLR.length)]);
            g2d.setStroke(STROKE[genInt(0, STROKE.length)]);
            g2d.drawArc(genInt(8, pixSize), genInt(8, hh - pixSize), 60, 10, -180, 90);
            g2d.drawArc(genInt(8, pixSize), genInt(8, hh), 60, 10, 0, 90);
            g2d.drawArc(genInt(8, pixSize), genInt(8, hh), 60, 10, -180, 90);
        }

        if (bDwLine) { //画一条干扰直线
            g2d.setColor(COLR[genInt(0, COLR.length)]);
            g2d.setStroke(STROKE[genInt(0, STROKE.length)]);
            g2d.drawLine(genInt(3, 16), genInt(3, h - num), genInt(pixSize << 1, w - 2), genInt(8, h - 2));
        }

        try {
            g2d.dispose();
            bimg.flush();
            ImageIO.write(bimg, imgMime, ostr);
        } catch (Exception ex) {
            Logger.warn(clazz, ex.toString());
        } finally {
            try {
                ostr.flush();
                ostr.close();
            } catch (IOException e) {
                Logger.error(clazz, e.toString());
            }
        }
    }

    // 常用函数，内部定义了部分变量值
    private static int genInt(int i, int j) {
        return DataUtil.genRndInt(i, j);
    }
}